package com.sky.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sky.constant.JwtClaimsConstant;
import com.sky.constant.MessageConstant;
import com.sky.constant.WeChatConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.exception.LoginFailedException;
import com.sky.exception.UserNotLoginException;
import com.sky.mapper.UserMapper;
import com.sky.properties.JwtProperties;
import com.sky.properties.WeChatProperties;
import com.sky.service.UserService;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.JwtUtil;
import com.sky.vo.OrderReportVO;
import com.sky.vo.UserLoginVO;
import com.sky.vo.UserReportVO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.HttpClients;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;
    @Autowired
    WeChatProperties weChatProperties;
    @Autowired
    JwtProperties jwtProperties;


    /**
     * 微信用户登录
     *
     * @param userLoginDTO
     * @return
     */
    @Override
    public UserLoginVO wxlogin(UserLoginDTO userLoginDTO) {
        //1. 获得小程序的信息，封装到map里，然后发送请求
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", userLoginDTO.getCode());
        map.put("grant_type", "authorization_code");//授权码，固定的
        //发送请求            http是凤凰岗好的
        String body = HttpClientUtil.doGet(WeChatConstant.WX_LOGIN, map);
        //获得id          使用JSONObject来进行json格式转换！！因为json可以get key获得响应的值
        String openid = (String) JSONObject.parseObject(body).get("openid");
        //判断是否登录

        if (openid == null) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        //判断用户是否存在（自动注册）
        User user = userMapper.select(openid);

        if (user == null) {
            //注册
            User use = User.builder().openid(openid).createTime(LocalDateTime.now()).build();
            //自增主键返回
            Integer id = userMapper.insert(use);
            user = use;
        }


        //生成jwt返回
        Map<String, Object> claim = new HashMap<>();
        //主要是存用户id,所以这里要主建自增
        claim.put(JwtClaimsConstant.USER_ID, user.getId());
        String jwt = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claim);
        return UserLoginVO.builder().id(user.getId())
                .openid(openid)
                .token(jwt)
                .build();

    }

    /**
     * 统计童虎数量
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO getNumByDate(LocalDate begin, LocalDate end) {
        //定义三个集合用于存放数据
        List<String> dateList = new ArrayList<>();
        List<String> newUserList = new ArrayList<>();
        List<String> totalUserList = new ArrayList<>();
        //对日期进行循环增加，查询响应的数据
        LocalDate fr = begin;
        while (!fr.isAfter(end)) {
            //获得该日的最大最小时间
            LocalDateTime beginTime = LocalDateTime.of(fr, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(fr, LocalTime.MAX);
            //封装到一个map丢进去
            Map<String, Object> map = new HashMap<>();
            map.put("beginTime", beginTime);
            map.put("endTime", endTime);
            //查询三个数据
            String allNum = userMapper.selectAllUser(map);
            String newNum = userMapper.selectNewUser(map);

            //非空添加数据
            dateList.add(fr.toString());
            newUserList.add(newNum != null ? newNum : " ");
            totalUserList.add(allNum!= null?allNum:" ");
            //日期加一
            fr = fr.plusDays(1);
        }
        //返回结果,用StringUtils.join对集合进行重构，让其符合返回的格式
        return  UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .build();


    }


}
